package com.starhub.api.sys.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.starhub.api.sys.user.service.LoginService;
import com.starhub.common.exception.AppException;
import com.starhub.common.security.util.JWTUtils;
import com.starhub.common.sys.user.LoginUser;
import com.starhub.engine.sys.user.service.SysUserService;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;

import java.nio.charset.StandardCharsets;

/**
 * @author
 * @version 1.0.0
 * @description
 * @createTime 2024/01/05
 */
@Slf4j
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private SysUserService sysUserService;


    // 自定义的spring security登录流程
    @Override
    public Map<String, Object> login(String username, String password) throws Exception {
        // 解密密码
        byte[] decodedBytes = Base64.getDecoder().decode(password);
        password = new String(decodedBytes, StandardCharsets.UTF_8);

        // 1.封装Authentication对象
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username,
                password);
        // 2.进行校验 (会自动调用UserDetailsService.loadUserByUsername)
        Authentication authenticate = authenticationManager.authenticate(authentication);
        // 3.如果校验为空,认证失败抛出异常
        if (Objects.isNull(authenticate)) {
            throw new AppException(403, "登录失败！");
        }
        // 4.取出，存入的用户对象
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        loginUser.getUser().setPassword(null);
        // 5.生产jwt字符串
        String loginUserStr = JSON.toJSONString(loginUser);
        // JwtUtils
        String jwt = JWTUtils.createJWT(loginUserStr); // 默认有效期为2小时
        Map<String, Object> loginObj = new HashMap<String, Object>();
        loginObj.put("userInfo", loginUser);
        loginObj.put("token", jwt);

        sysUserService.updateLastLogin(loginUser); //更新最后一次登录时间
        return loginObj;
    }

}
